import { EventEmitter, Injectable } from '@angular/core';
import { ScenarioService } from './scenario.service';
import * as signalR from "@microsoft/signalr";
import { environment } from 'src/environment/environment';
import { NotifyType } from '../enums';
import { NotifyMessage, NotifyState, NotifyCommand, NotifyError, ScenarioConfig, INotifyEvent, ICommand, NotifyFieldUpdated } from '../models';

@Injectable()
export class ScenarioMonitorService {

  onConnectChanged: EventEmitter<boolean> = new EventEmitter();
  onMessage: EventEmitter<NotifyMessage> = new EventEmitter();
  onState: EventEmitter<NotifyState> = new EventEmitter();
  onCmd: EventEmitter<ICommand> = new EventEmitter();
  onError: EventEmitter<NotifyError> = new EventEmitter();
  onFieldUpdated: EventEmitter<NotifyFieldUpdated> = new EventEmitter();
  onScenarioChanged: EventEmitter<ScenarioConfig> = new EventEmitter();


  scenario?: ScenarioConfig;
  private connection?: signalR.HubConnection;
  connected: boolean = false;

  constructor(private service: ScenarioService) {
    this.onConnectChanged.subscribe(e => {
      this.connected = e;
    });

    const connection =
      new signalR.HubConnectionBuilder()
        .withUrl(environment.signalRBaseUrl)
        .withAutomaticReconnect()
        .build();

    connection.on("Notify", (e: INotifyEvent) => {
      switch (e.Type) {
        case NotifyType.Message:

          this.onMessage.emit(e);
          break;
        case NotifyType.Command:
          this.onCmd.emit(e.Cmd);
          break;
        case NotifyType.State:
          this.onState.emit(e);
          break;
        case NotifyType.Error:
          this.onError.emit(e);
          break;
        case NotifyType.FieldUpdated:
          this.onFieldUpdated.emit(e);
          break;
        default:
          console.log(e);
          break;
      }
    });

    connection.start().then(() => {
      this.onConnectChanged.emit(true);
    });

    connection.onreconnecting(e => {
      this.onConnectChanged.emit(false);
    });
    connection.onreconnected(e => {
      this.onConnectChanged.emit(true);
    });

    this.connection = connection;

  }

  load(id: string) {
    if (this.connected) {
      this.service.get(id).subscribe(project => {
        this.scenario = project;
        this.onScenarioChanged.emit(project);

        this.connection?.send("Load", this.scenario.Id);
      });
    }

  }
  unload() {
    this.connection?.send("Unload", this.scenario!.Id);
  }
  start() {
    this.connection?.send("Start", this.scenario!.Id);
  }
  stop() {
    this.connection?.send("Stop", this.scenario!.Id);
  }
}
